[TDR Generic表][C++ SDK]遍历表数据
1. 接口说明
该接口可用于全表遍历(example路径:examples/tcaplus/C++_tdr1.0_asyncmode_generic_simpletable/SingleOperation/travers)
注意:
- 调用 TcaplusServiceRequest::SetFieldName接口,填入需要的key字段和value字段,可以部分字段遍历。
- 每个表同时只能有一个遍历器在运行,单个gamesvr同时最多支持8个遍历器,建议遍历器要少一点,否则对正常的读写访问时延有影响。
2. 版本要求
无版本要求
3. 准备工作
参见准备工作文档,完成使用该接口前的准备工作,并创建如下TDR Generic表,并使用TDR工具将XML表转换为C++代码。PLAYERONLINECNT表描述文件table_test.xml
<?xml version="1.0" encoding="GBK" standalone="yes" ?>
<metalib name="tcaplus_tb" tagsetversion="1" version="1">
<struct name="PLAYERONLINECNT" version="1" primarykey="TimeStamp,GameSvrID" splittablekey="TimeStamp">
<entry name="TimeStamp" type="uint32" desc="单位为分钟" />
<entry name="GameSvrID" type="string" size="64" />
<entry name="GameAppID" type="string" size="64" desc="gameapp id" />
<entry name="OnlineCntIOS" type="uint32" defaultvalue="0" desc="ios在线人数" />
<entry name="OnlineCntAndroid" type="uint32" defaultvalue="0" desc="android在线人数" />
<entry name="BinaryLen" type="smalluint" defaultvalue="1" desc="数据来源数据长度;长度为0时,忽略来源检查"/>
<entry name="binary" type="tinyint" desc="二进制" count= "1000" refer="BinaryLen" />
<entry name="binary2" type="tinyint" desc="二进制2" count= "1000" refer="BinaryLen" />
<entry name="strstr" type="string" size="64" desc="字符串"/>
<index name="index_id" column="TimeStamp"/>
</struct>
</metalib>
准备工作完成后,将会获得以下信息,这些信息在使用SDK时会被用到:
- 目录服务器地址列表
- 业务ID
- 业务访问密码
- 游戏区ID
- 数据表名
4. 示例代码
4.1 异步调用示例代码
示例代码的基本执行过程:
- 定义表配置参数
- 创建日志句柄;
- 创建客户端;
- 发送请求;
- 处理响应;
- 销毁客户端。
- example主函数框架;
第1,2,3,6,7步是所有示例的通用代码,重点关注第4步和第5步,发送请求和处理响应
4.1.1 定义数据库表配置参数(代码路径:examples/tcaplus/C++_tdr1.0_asyncmode_generic_simpletable/SingleOperation/travers/main.cpp)
主要设置表的相关配置参数,在代码文件的头部
// 目标业务的tcapdir地址
static const char DIR_URL_ARRAY[][TCAPLUS_MAX_STRING_LENGTH] =
{
"tcp://10.191.***.99:9999",
"tcp://10.191.***.88:9999"
};
// 目标业务的tcapdir 地址个数
static const int32_t DIR_URL_COUNT = 2;
// 目标业务的集群ID
static const int32_t APP_ID = 3;
// 目标业务的表格组ID
static const int32_t ZONE_ID = 1;
// 目标业务的业务密码
static const char * SIGNATURE = "*******";
// 目标业务的表名 PLAYERONLINECNT
static const char * TABLE_NAME = "PLAYERONLINECNT";
4.1.2 创建日志句柄(代码路径:examples/tcaplus/C++_tdr1.0_asyncmode_generic_simpletable/SingleOperation/travers/main.cpp)
通过日志配置文件tlogconf.xml创建日志句柄,用于SDK的日志打印
//TCaplus service 日志类
TcaplusService::TLogger* g_pstTlogger;
LPTLOGCATEGORYINST g_pstLogHandler;
LPTLOGCTX g_pstLogCtx;
int32_t InitLog()
{
// 日志配置文件的绝对路径
const char* sLogConfFile = "tlogconf.xml";
// 日志类名
const char* sCategoryName = "mytest";
//从配置文件初始化日志句柄
g_pstLogCtx = tlog_init_from_file(sLogConfFile);
if (NULL == g_pstLogCtx)
{
fprintf(stderr, "tlog_init_from_file failed.\n");
return -1;
}
// 获取日志类
g_pstLogHandler = tlog_get_category(g_pstLogCtx, sCategoryName);
if (NULL == g_pstLogHandler)
{
fprintf(stderr, "tlog_get_category(mytest) failed.\n");
return -2;
}
// 初始化日志句柄
g_pstTlogger = new TcaplusService::TLogger(g_pstLogHandler);
if (NULL == g_pstTlogger)
{
fprintf(stderr, "TcaplusService::TLogger failed.\n");
return -3;
}
return 0;`
}
4.1.3 创建SDK客户端(代码路径:examples/tcaplus/C++_tdr1.0_asyncmode_generic_simpletable/SingleOperation/travers/main.cpp)
通过该代码创建一个Tcaplus客户端,该客户端只允许单线程使用,多线程模型可以在每个线程上初始化一个客户端实例
//Tcaplus service API的客户端主类
TcaplusService::TcaplusServer g_stTcapSvr;
//表的meta信息
extern unsigned char g_szMetalib_tcaplus_tb[];
LPTDRMETA g_szTableMeta = NULL;
int32_t InitServiceAPI()
{
// 初始化
int32_t iRet = g_stTcapSvr.Init(g_pstTlogger, /*module_id*/0, /*app id*/APP_ID, /*zone id*/ZONE_ID, /*signature*/SIGNATURE);
if (0 != iRet)
{
tlog_error(g_pstLogHandler, 0, 0, "g_stTcapSvr.Init failed, iRet: %d.", iRet);
return iRet;
}
// 添加目录服务器
for (int32_t i = 0; i< DIR_URL_COUNT; i++)
{
iRet = g_stTcapSvr.AddDirServerAddress(DIR_URL_ARRAY[i]);
if (0 != iRet)
{
tlog_error(g_pstLogHandler, 0, 0, "g_stTcapSvr.AddDirServerAddress(%s) failed, iRet: %d.", DIR_URL_ARRAY[i], iRet);
return iRet;
}
}
// 取得表的meta描述
g_szTableMeta = tdr_get_meta_by_name((LPTDRMETALIB)g_szMetalib_tcaplus_tb, TABLE_NAME);
if(NULL == g_szTableMeta)
{
tlog_error(g_pstLogHandler, 0, 0,"tdr_get_meta_by_name(%s) failed.", TABLE_NAME);
return -1;
}
// 注册数据库表(连接dir服务器,认证,获取表路由),10s超时
iRet = g_stTcapSvr.RegistTable(TABLE_NAME, g_szTableMeta, /*timeout_ms*/10000);
if(0 != iRet)
{
tlog_error(g_pstLogHandler, 0, 0, "g_stTcapSvr.RegistTable(%s) failed, iRet: %d.", TABLE_NAME, iRet);
return iRet;
}
// 连接表对应的所有tcaplus proxy服务器
iRet = g_stTcapSvr.ConnectAll(/*timeout_ms*/10000, 0);
if(0 != iRet)
{
tlog_error(g_pstLogHandler, 0, 0, "g_stTcapSvr.ConnectAll failed, iRet: %d.", iRet);
return iRet;
}
return 0;
}
4.1.4 发送请求(代码路径:examples/tcaplus/C++_tdr1.0_asyncmode_generic_simpletable/SingleOperation/travers/main.cpp)
创建请求,并且添加记录,使用客户端发送请求
// 遍历启动后就会不断收到该表的记录
int32_t TraversCase(bool &bContinue)
{
TcaplusServiceTraverser* traverser = g_stTcapSvr.GetTableTraverser(ZONE_ID, TABLE_NAME);
if(NULL == traverser)
{
tlog_error(g_pstLogHandler, 0, 0, "g_stTcapSvr.GetTableTraverser(%d, %s) failed.", ZONE_ID, TABLE_NAME);
return -1;
}
// 设置遍历的字段值
const char* psFieldName [] = {"GameAppID","OnlineCntIOS","OnlineCntAndroid"};
int32_t iRet = traverser->SetFieldNames(psFieldName, 3);
if(0 != iRet)
{
tlog_error(g_pstLogHandler, 0, 0, "traverser->SetFieldNames failed, ret: %d.", iRet);
return -2;
}
// 设置表的类型TCAPLUS_TABLE_TYPE_GENERIC 和 TCAPLUS_TABLE_TYPE_LIST
traverser->SetTableType(TCAPLUS_TABLE_TYPE_GENERIC);
// 设置每次请求对应的回包数目
iRet = traverser->SetResNumPerReq(1);
if(0 != iRet)
{
tlog_error(g_pstLogHandler, 0, 0, "traverser->SetResNumPerReq failed, ret: %d.", iRet);
return -3;
}
iRet = traverser->Start();
if(0 != iRet)
{
tlog_error(g_pstLogHandler, 0, 0, "traverser->Start failed, ret: %d.", iRet);
return -3;
}
while(true)
{
// 接收响应包
RecvPackage();
bContinue = false;
switch(traverser->GetState())
{
case TcaplusServiceTraverser::ST_NORMAL:
{//遍历器状态正常
bContinue = true;
break;
}
case TcaplusServiceTraverser::ST_IDLE:
{//遍历完成
bContinue = false;
traverser->Stop();
tlog_info(g_pstLogHandler, 0, 0, "traverser (%d, %s) finish.", APP_ID, TABLE_NAME);
break;
}
default:
{//遍历器状态异常
bContinue = false;
traverser->Stop();
tlog_error(g_pstLogHandler, 0, 0, "traverser (%d, %s) encountered an error, current state: %d.", APP_ID, TABLE_NAME, traverser->GetState());
break;
}
}
// 如果不进行继续遍历后退出while循环
if(!bContinue)
{
break;
}
}
return 0;
}
4.1.5 处理响应(代码路径:examples/tcaplus/C++_tdr1.0_asyncmode_generic_simpletable/SingleOperation/travers/main.cpp)
处理响应,判断响应的返回值做响应处理,返回成功则从响应中获取记录
int32_t RecvPackage()
{
uint32_t dwHandleCnter = 0;
uint32_t dwMaxHandleCnter = MAX_HANDLE_COUNTER_ONBUSY;
// 当循环次数达到MAX_HANDLE_COUNTER_ONBUSY仍然没有接收到TOTAL_SEND_RECV_NUM的响应包时,退出接收包的循环。
while(dwHandleCnter++ < dwMaxHandleCnter)
{
// warning 该函数返回的response指针是全局共用的,所以使用后请勿手动调用response->Destruct或者delete response。
TcaplusServiceResponse* pstTcapRspRcved = NULL;
// 接收响应包
// @retval <0 失败,返回对应的错误码。
// @retval 0 成功,但未收到完整的响应包。
// @retval 1 成功,收到1个完整的响应包,此时输出参数response为非NULL指针。
int32_t iRet = g_stTcapSvr.RecvResponse(pstTcapRspRcved);
if (iRet < 0)
{
tlog_error(g_pstLogHandler, 0, 0, "g_stTcapSvr.RecvResponse failed. ret: %d.", iRet);
}
else
{
if(1 == iRet && NULL != pstTcapRspRcved)
{
HandleResponse(pstTcapRspRcved);
}
else
{
break;
}
}
}
return 0;
}
// 响应处理函数
int32_t HandleResponse(TcaplusServiceResponse* pstTcapRspRcved)
{
if(NULL == pstTcapRspRcved)
{
return -1;
}
int32_t result = pstTcapRspRcved->GetResult();
const char* table_name = pstTcapRspRcved->GetTableName();
int32_t cmd = pstTcapRspRcved->GetCmd();
if(TCAPLUS_API_TABLE_TRAVERSE_RES != cmd)
{
printf("receive a uninstresting response package.\n");
return -2;
}
// 处理回包
HandleTraverse(pstTcapRspRcved);
return 0;
}
int32_t HandleTraverse(TcaplusServiceResponse* pstTcapRspRcved)
{
if(NULL == pstTcapRspRcved)
{
return -1;
}
int32_t iResult = pstTcapRspRcved->GetResult();
if( 0 != iResult)
{
tlog_error(g_pstLogHandler, 0, 0, "GetResult failed iRet[%d] ret_msg[%s]\n", iResult, TcapErrCode::GetErrStr(iResult));
return -2;
}
int32_t iRet = 0;
printf("GetRecordCount: %d. \n", pstTcapRspRcved->GetRecordCount());
int32_t iCount = 0;
while(iCount++ < pstTcapRspRcved->GetRecordCount())
{
const TcaplusServiceRecord *pstTcapRecord = NULL;
iRet = pstTcapRspRcved->FetchRecord(pstTcapRecord);
if(0 != iRet || NULL == pstTcapRecord)
{
printf("FetchRecord %dth failed.\n", iCount);
continue;
}
PLAYERONLINECNT stPLAYERONLINECNT;
memset(&stPLAYERONLINECNT, 0, sizeof(stPLAYERONLINECNT));
// 获得基于TDR描述的record数据
iRet = pstTcapRecord->GetData(&stPLAYERONLINECNT, sizeof(stPLAYERONLINECNT));
if(0 != iRet)
{
printf("GetData failed iRet = %d \n",iRet);
return -4;
}
printf("---------------------receive response,the record is ------------------------\n");
printf("dwTimeStamp: %d \n", stPLAYERONLINECNT.dwTimeStamp);
printf("szGameSvrID: %s \n", stPLAYERONLINECNT.szGameSvrID);
printf("szGameAppID: %s \n", stPLAYERONLINECNT.szGameAppID);
printf("dwOnlineCntIOS: %d \n", stPLAYERONLINECNT.dwOnlineCntIOS);
printf("dwOnlineCntAndroid: %d \n", stPLAYERONLINECNT.dwOnlineCntAndroid);
}
return iRet;
}
4.1.6 销毁客户端(代码路径:examples/tcaplus/C++_tdr1.0_asyncmode_generic_simpletable/SingleOperation/travers/main.cpp)
进程退出时,先调用客户端的Fini函数,销毁客户端,再销毁日志句柄,防止客户端退出时打日志coredump
void Finish()
{
//此处的逻辑是防止遍历器完成了,但是包还没收完
for(int32_t i=0; i<TCAPLUS_MAX_COUNT_WHEN_FINISH; i++)
{
RecvPackage();
}
//先销毁客户端
g_stTcapSvr.Fini();
tlog_info(g_pstLogHandler, 0, 0, "mytest finish!");
//再销毁日志句柄
delete g_pstTlogger;
g_pstTlogger = NULL;
tlog_fini_ctx(&g_pstLogCtx);
}
4.1.7 example遍历主框架(代码路径:examples/tcaplus/C++_tdr1.0_asyncmode_generic_simpletable/SingleOperation/travers/main.cpp)
通过实现回调函数的三个函数指针,proc主框架会调用相应的函数发送请求,接收响应和超时处理,该框架所有例子通用
int32_t Proc()
{
while(true)
{
bool bContinue = false;
// 发送遍历请求,如果处理遍历中,则bContinue被赋值为true
TraversCase(bContinue);
// 停止遍历,退出
if(!bContinue)
{
break;
}
}
return 0;
}
int32_t Init()
{
int32_t ret = 0;
ret = InitLog();
if (0 != ret)
{
printf("InitLog failed! ret = %d \n",ret);
return ret;
}
ret = InitServiceAPI();
if (0 != ret)
{
printf("InitServiceAPI failed! ret = %d \n",ret);
return ret;
}
return ret;
}
int32_t main(int32_t argc, char *argv[])
{
int32_t iRet = 0;
// 初始化
iRet = Init();
if (0 != iRet)
{
tlog_error(g_pstLogHandler, 0, 0, "Init failed, iRet: %d, please check the mytest.log for detail. ", iRet);
printf("Init failed, iRet: %d, please check the mytest.log for detail. \n", iRet);
return iRet;
}
// 处理逻辑
iRet = Proc();
if (0 != iRet)
{
tlog_error(g_pstLogHandler, 0, 0, "Proc failed, iRet: %d, please check the mytest.log for detail. ", iRet);
printf("Proc failed, iRet: %d, please check the mytest.log for detail. \n", iRet);
return iRet;
}
// 回收操作
Finish();
return 0;
}
5. 请求对象(request)中的方法说明
注:此处未列出请求对象的其它方法,即表示该方法在查询数据的场景不需要使用,误用可能会导致报错。
/**
@brief 重置请求数据,以便用于下一次请求准备
@param [IN] cmd 请求操作类型,具体参见 \link TCaplusApiCmds \endlink
@param [IN] user_buffer 用户自定义信息缓冲区,作为异步信息携带给服务端,回包时原样返回
@param [IN] buffer_data_size 自定义缓冲区中的数据大小,支持的最大长度未1024
@param [IN] async_id 请求对应的异步事务ID,tcaplus会将其值不变地通过请求对应的响应消息带回来
@param [IN] seq 请求消息序列号,目前Tcaplus不会在Service Api侧将请求消息序列号做自动加1操作,tcaplus在服务器端也不会处理此消息序列号值,tcaplus会将此值不变地通过请求对应的响应消息带回来
@param [IN] result_flag 响应标志.该参数的含义和"int SetResultFlag(IN char result_flag)"中参数IN char result_flag的含义是相同的。
@retval 0 成功
@retval <0 失败,返回对应的错误码。
@note user_buffer参数中保存的自定义数据最大长度为1024
*/
int Init(IN TCaplusApiCmds cmd,
IN const char* user_buffer = NULL, IN const size_t buffer_data_size = 0, IN uint64_t async_id = 0,
IN int32_t seq = 0, IN char result_flag = 0);
/**
@brief 获取请求操作类型
@retval TCAPLUS_API_INVALID_REQ 未初始化时,返回此无效命令号。
@retval \link TCaplusApiCmds \endlink
*/
TCaplusApiCmds GetCmd() const;
/**
@brief 获取请求操作的表名
@param [OUT] table_name_size 若table_name_size不为NULL,则向其所指位置写入表名长度。
@retval NULL TcaplusServiceRequest对象未初始化时返回NULL。
@retval !NULL 指向操作的表名的指针。
*/
const char* GetTableName(OUT size_t* table_name_size = NULL) const;
/**
@brief 获取请求操作的游戏区ID
@retval 操作游戏区ID
*/
int GetZoneId() const;
/**
@brief 设置用户缓存,应答将携带返回
@param [IN] user_buffer 用户缓存指针
@param [IN] buffer_data_size 用户缓存长度,支持的最大长度为1024字节
@retval 0 设置成功
@retval <0 失败,返回对应的错误码。
*/
int SetUserBuff(IN const char* user_buffer, IN const size_t buffer_data_size);
/**
@brief 获取请求中的用户缓存信息
@param [OUT] buffer_data_size 若buffer_data_size不为NULL,则向其所指位置写入表名长度。
@retval NULL 当TcaplusServiceRequest对象未初始化时返回NULL。
@retval !NULL 用户缓存的首指针。
*/
const char* GetUserBuff(OUT size_t* buffer_data_size = NULL) const;
/**
@brief 设置请求对应的异步事务ID。
@param [IN] async_id 请求对应的异步事务ID,tcaplus会将其值不变地通过请求对应的响应消息带回来
@retval 0 设置成功
@retval <0 失败,返回对应的错误码。
*/
int SetAsyncID(IN uint64_t async_id);
/**
@brief 获取请求异步事务ID
@retval 异步事务ID
*/
uint64_t GetAsynID() const;
/**
@brief 设置请求序列号
@retval 0 设置成功
@retval <0 失败,返回对应的错误码。通常因为未初始化。
*/
int SetSequence(IN int32_t seq);
/**
@brief 获取请求序列号
@retval 请求序列号
*/
int32_t GetSequence() const;
/**
@brief 获取请求的通用标志位
@return 返回请求的通用标志位
@note 有效的标志位列表及详细解释请参考 SetFlags()
*/
int32_t GetFlags() const;
/**
@brief 向请求中添加一条记录。
@param [IN] index 用于List操作,通常>=0,表示该Record在所属List中的Index(非下标)。
用于List表中的TCAPLUS_API_LIST_ADDAFTER_REQ,TCAPLUS_API_LIST_ADDAFTER_BATCH_REQ, index可以取值TCAPLUS_API_LIST_PRE_FIRST_INDEX或TCAPLUS_API_LIST_LAST_INDEX命令号。
index是辅助key,tcaplus会自动维护其唯一性,新插入的记录index会往上自增。
当cmd是TCAPLUS_API_LIST_ADDAFTER_REQ时,表示记录插入在该index所在的记录之后(隐含约束:index对应的记录必须已存在);
此时index还支持以下特殊值:
TCAPLUS_API_LIST_PRE_FIRST_INDEX:新元素插入在第一个元素之前
TCAPLUS_API_LIST_LAST_INDEX:新元素插入在最后一个元素之后
对于Generic操作,index无意义将被忽略。
@retval \link TcaplusRecord \endlink 返回记录指针
@retval NULL 添加记录失败
*/
TcaplusServiceRecord* AddRecord(IN int32_t index = -1);
/**
@brief 可视化输出请求
@param [INOUT] buffer 缓冲区指针
@param [IN] buffer_size 缓冲区大小
@retval 打包的缓冲区指针,内容以'\0'结尾
*/
const char* Print(INOUT char* buffer, IN size_t buffer_size);
/**
@brief 获取最后一次记录的错误信息。只有初始化logger参数为NULL时,request才会自动生成该缓冲区;否则会自动写日志,本函数返回NULL。
@retval 最后错误信息缓冲区。
*/
const char* GetLastError();
/**
@brief 设置需要查询或更新的Value字段名称列表,即部分Value字段查询和更新,
可用于get, batchget, partkeyget, listget, listgetall, listreplace, replace, update, tabletraverse操作。
@param [IN] field_name 需要查询或更新的字段名称列表,每个字段名称不超过32字节,名称以'\0'结尾
@param [IN] field_count 字段名称个数
@retval 0 设置成功
@retval <0 设置失败,具体错误参见 \link ErrorCode \endlink
@note 当在更新操作(replace, batchReplace, update, batchUpdate, listreplace操作)中使用SetData()函数设置数据时,
使用SetData()函数设置数据时,如果只需要更新部分字段,可以使用该
函数设定需要更新的字段,但是,注意,在进行部分字段更新时,一
定要先调用SetData()函数,然后再调用SetFieldNames()函数,这样才能达到部分
部分字段更新的功能。
@note 注意,在使用该函数设置字段名时,字段名只能包含value字段名,不能包含key字段名
*/
int32_t SetFieldNames(IN const char* field_name[], IN const unsigned field_count);
/**
@brief 设置需要查询的Value字段名称,即部分Value字段查询,
可用于get, batchget, partkeyget, listget, listgetall操作。
@param [IN] field_name 添加的需要查询的字段名称,每个字段名称不超过32字节,名称以'\0'结尾
@retval 0 设置成功
@retval <0 设置失败,具体错误参见 \link ErrorCode \endlink
*/
int32_t AddFieldName(IN const char* field_name);
/**
@brief 设置请求的通用标志位,可以通过"按位或"操作同时设定多个值
@param [IN] flag. 请求标志位的值
@retval 0 设置成功
@retval <0 失败,返回对应的错误码。通常因为未初始化。
@note 有效的标志位包括:
* TCAPLUS_FLAG_FETCH_ONLY_IF_MODIFIED:
* "数据变更才取回"标志位。在发起读操作之前,用户代码通过 TcaplusServiceRecord::SetVersion()
* 带上本地缓存数据的版本号,并将此标志置位,那么存储端检测到当前数据与API本地缓存的数据版本
* 一致时,表明该记录未发生过修改,API缓存的数据是最新的,因此在响应中将不会携带实际的数据,
* 只是返回 TcapErrCode::COMMON_INFO_DATA_NOT_MODIFIED 的错误码
*
* 在请求中设置了此标志位之后,收到响应后应首先通过 TcaplusServiceResponse::GetFlags() 来获知
* 发送请求时是否设置了TCAPLUS_FLAG_FETCH_ONLY_IF_MODIFIED标志.
*
* 只有如下请求支持设置此标志:
* TCAPLUS_API_GET_REQ,
* TCAPLUS_API_LIST_GET_REQ,
* TCAPLUS_API_LIST_GETALL_REQ
*
* TCAPLUS_FLAG_FETCH_ONLY_IF_EXPIRED:
* "数据过期才取回"标志位。在发起读操作之前,用户代码通过 SetExpireTime() 设定数据过期时间,
* 并将此标志置位,那么存储端若检测到记录在指定时间内发生过更新,则将数据返回,
* 否则不返回实际数据,只是返回 TcapErrCode::COMMON_INFO_DATA_NOT_MODIFIED 的错误码。
*
* 在请求中设置了此标志位之后,收到响应后应首先通过 TcaplusServiceResponse::GetFlags() 来获知
* 发送请求时是否设置了 TCAPLUS_FLAG_FETCH_ONLY_IF_EXPIRED 标志.
*
* 只有如下请求支持设置此标志:
* TCAPLUS_API_BATCH_GET_REQ
*
* TCAPLUS_FLAG_ONLY_READ_FROM_SLAVE
* 设置此标志后,读请求将会直接发送给Tcapsvr Slave 节点。
* Tcapsvr Slave 通常比较空闲,设置此标志有助于充分利用Tcapsvr Slave 资源。
*
* 适用场景:
* 对于数据实时性要求不高的读请求,
* 包括generic表和list表的所有读请求以及batchget,遍历请求
*
* TCAPLUS_FLAG_LIST_RESERVE_INDEX_HAVING_NO_ELEMENTS
* 设置此标志后,List表删除最后一个元素时需要保留index和version。
* ListDelete ListDeleteBatch ListDeleteAll操作在删除list表最后一个元素时,
* 设置此标志在写入新的List记录时,版本号依次增长,不会被重置为1。
*
* 适用场景:
* 业务需要确定某个表在删除最后一个元素时是否需要保留index和version
* 主要涉及List表的使用体验
*
*/
int SetFlags(int32_t flag);
/**
@brief 清理请求的通用标志位,可以通过"按位或"操作同时设定多个值
@param [IN] flag. 请求标志位的值
@retval 0 设置成功
@retval <0 失败,返回对应的错误码。通常因为未初始化。
@note 有效的标志位列表及详细解释请参考 SetFlags()
*/
int ClearFlags(int32_t flag);
/**
@brief 设置响应标志。主要用于Generic表的insert、increase、replace、update、delete操作和list表的单个delete replace操作。
@param [IN] result_flag 请求标志:
0表示: 只需返回操作执行成功与否
1表示: 返回与请求字段一致
2表示: 须返回变更记录的所有字段最新数据
3表示: 须返回变更记录的所有字段旧数据
@retval 0 设置成功
@retval <0 失败,返回对应的错误码。通常因为未初始化。
@note 如果使用该接口,部分请求标志实际上是不支持的,强烈建议使用SetResultFlagForSuccess接口和SetResultFlagForFail接口
*/
int SetResultFlag(IN char result_flag);
/**
@brief 设置响应标志。主要是本次请求成功执行后返回给前端的数据
result_flag 的取值范围如下:
TCaplusValueFlag_NOVALUE = 0, // 不返回任何返回值
TCaplusValueFlag_SAMEWITHREQUEST = 1, // 返回同请求一致的值
TCaplusValueFlag_ALLVALUE = 2, // 返回tcapsvr端操作后所有字段的值
TCaplusValueFlag_ALLOLDVALUE = 3, // 返回tcapsvr端操作前所有字段的值
下面是各个支持的命令字在设置不同的result_flag下执行成功后返回给API端的数据详细情况:
1. TCAPLUS_API_INSERT_REQ TCAPLUS_API_BATCH_INSERT_REQ
如果设置的是TCaplusValueFlag_NOVALUE, 则操作成功后不返回数据
如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作成功后返回和请求一致的数据
如果设置的是TCaplusValueFlag_ALLVALUE, 则操作成功后返回本次insert操作后的数据
如果设置的是TCaplusValueFlag_ALLOLDVALUE, 则操作成功后返回空数据
2. TCAPLUS_API_REPLACE_REQ TCAPLUS_API_BATCH_REPLACE_REQ
如果设置的是TCaplusValueFlag_NOVALUE, 则操作成功后不返回数据
如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作成功后返回和请求一致的数据
如果设置的是TCaplusValueFlag_ALLVALUE, 则操作成功后返回本次replace操作后的数据
如果设置的是TCaplusValueFlag_ALLOLDVALUE, 则操作成功后返回tcapsvr端操作前的数据, 如果tcapsvr端没有数据,即返回为空
3. TCAPLUS_API_UPDATE_REQ TCAPLUS_API_BATCH_UPDATE_REQ
如果设置的是TCaplusValueFlag_NOVALUE, 则操作成功后不返回数据
如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作成功后返回和请求一致的数据
如果设置的是TCaplusValueFlag_ALLVALUE, 则操作成功后返回本次update操作后的数据
如果设置的是TCaplusValueFlag_ALLOLDVALUE, 则操作成功后返回tcapsvr端操作前的数据
4. TCAPLUS_API_INCREASE_REQ
如果设置的是TCaplusValueFlag_NOVALUE, 则操作成功后不返回数据
如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作成功后返回和请求一致的数据
如果设置的是TCaplusValueFlag_ALLVALUE, 则操作成功后返回本次increase操作后的数据
如果设置的是TCaplusValueFlag_ALLOLDVALUE, 则操作成功后返回tcapsvr端操作前的数据, 如果tcapsvr端没有数据,即返回为空
5. TCAPLUS_API_DELETE_REQ TCAPLUS_API_BATCH_DELETE_REQ
如果设置的是TCaplusValueFlag_NOVALUE, 则操作成功后不返回数据
如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作成功后返回和请求一致的数据
如果设置的是TCaplusValueFlag_ALLVALUE, 则操作成功后返回空数据
如果设置的是TCaplusValueFlag_ALLOLDVALUE, 则操作成功后返回tcapsvr端操作前的数据
6. TCAPLUS_API_LIST_DELETE_BATCH_REQ
如果设置的是TCaplusValueFlag_NOVALUE, 则操作成功后不返回数据
如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作成功后返回和请求一致的数据, 暂时没有实现
如果设置的是TCaplusValueFlag_ALLVALUE, 则操作成功后不返回数据
如果设置的是TCaplusValueFlag_ALLOLDVALUE, 则操作成功后返回tcapsvr端操作前的数据, 凡是本次成功删除的index对应的数据都会返回
7. TCAPLUS_API_LIST_ADDAFTER_REQ
如果设置的是TCaplusValueFlag_NOVALUE, 则操作成功后不返回数据
如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作成功后返回和请求一致的数据, 暂时没有实现
如果设置的是TCaplusValueFlag_ALLVALUE, 则操作成功后, 返回本次插入的记录和本次淘汰的数据记录
如果设置的是TCaplusValueFlag_ALLOLDVALUE, 则操作成功后不返回数据
8. TCAPLUS_API_LIST_DELETE_REQ
如果设置的是TCaplusValueFlag_NOVALUE, 则操作成功后不返回数据
如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作成功后返回和请求一致的数据, 暂时没有实现
如果设置的是TCaplusValueFlag_ALLVALUE, 则操作成功后返回空数据
如果设置的是TCaplusValueFlag_ALLOLDVALUE, 则操作成功后返回tcapsvr端listdelete前的数据
9. TCAPLUS_API_LIST_REPLACE_REQ
如果设置的是TCaplusValueFlag_NOVALUE, 则操作成功后不返回数据
如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作成功后返回和请求一致的数据, 暂时没有实现
如果设置的是TCaplusValueFlag_ALLVALUE, 则操作成功后返回tcapsvr端listreplace后的数据
如果设置的是TCaplusValueFlag_ALLOLDVALUE, 则操作成功后返回tcapsvr端listreplace前的数据
10. TCAPLUS_API_LIST_REPLACE_BATCH_REQ
如果设置的是TCaplusValueFlag_NOVALUE, 操作成功后返回和请求一致的数据
如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作成功后返回和请求一致的数据
如果设置的是TCaplusValueFlag_ALLVALUE, 则操作成功后返回tcapsvr端listreplace后的数据
如果设置的是TCaplusValueFlag_ALLOLDVALUE, 则操作成功后返回tcapsvr端listreplace前的数据
@param [IN] result_flag 请求标志:
0表示: 只需返回操作执行成功与否
1表示: 返回与请求字段一致
2表示: 须返回变更记录的所有字段最新数据
3表示: 须返回变更记录的所有字段旧数据
从而知道是哪个key对应的记录失败了
@retval 0 设置成功
@retval <0 失败,返回对应的错误码。通常因为未初始化。
*/
int SetResultFlagForSuccess (char result_flag);
/**
@brief 设置响应标志。主要是本次请求执行失败后返回给前端的数据
result_flag 的取值范围如下:
TCaplusValueFlag_NOVALUE = 0, // 不返回任何返回值
TCaplusValueFlag_SAMEWITHREQUEST = 1, // 返回同请求一致的值
TCaplusValueFlag_ALLVALUE = 2, // 返回tcapsvr端操作后所有字段的值
TCaplusValueFlag_ALLOLDVALUE = 3, // 返回tcapsvr端操作前所有字段的值
下面是各个支持的命令字在设置不同的result_flag下执行失败后返回给API端的数据详细情况:
1. TCAPLUS_API_INSERT_REQ TCAPLUS_API_BATCH_INSERT_REQ
如果设置的是TCaplusValueFlag_NOVALUE, 则操作失败后不返回数据
如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作失败后返回和请求一致的数据
如果设置的是TCaplusValueFlag_ALLVALUE, 不合理场景
如果设置的是TCaplusValueFlag_ALLOLDVALUE, 如果获取到了tcapsvr端的数据则返回tcpasvr端的数据,如果没有获取到tcapsvr端的数据则返回空
2. TCAPLUS_API_REPLACE_REQ TCAPLUS_API_BATCH_REPLACE_REQ
如果设置的是TCaplusValueFlag_NOVALUE, 则操作失败后不返回数据
如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作失败后返回和请求一致的数据
如果设置的是TCaplusValueFlag_ALLVALUE, 不合理场景
如果设置的是TCaplusValueFlag_ALLOLDVALUE, 如果获取到了tcapsvr端的数据则返回tcpasvr端的数据,如果没有获取到tcapsvr端的数据则返回空
3. TCAPLUS_API_UPDATE_REQ TCAPLUS_API_BATCH_UPDATE_REQ
如果设置的是TCaplusValueFlag_NOVALUE, 则操作失败后不返回数据
如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作失败后返回和请求一致的数据
如果设置的是TCaplusValueFlag_ALLVALUE, 不合理场景
如果设置的是TCaplusValueFlag_ALLOLDVALUE, 如果获取到了tcapsvr端的数据则返回tcpasvr端的数据,如果没有获取到tcapsvr端的数据则返回空
4. TCAPLUS_API_INCREASE_REQ
如果设置的是TCaplusValueFlag_NOVALUE, 则操作失败后不返回数据
如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作失败后返回和请求一致的数据
如果设置的是TCaplusValueFlag_ALLVALUE, 不合理场景
如果设置的是TCaplusValueFlag_ALLOLDVALUE, 如果获取到了tcapsvr端的数据则返回tcpasvr端的数据,如果没有获取到tcapsvr端的数据则返回空
5. TCAPLUS_API_DELETE_REQ TCAPLUS_API_BATCH_DELETE_REQ
如果设置的是TCaplusValueFlag_NOVALUE, 则操作失败后不返回数据
如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作失败后返回和请求一致的数据
如果设置的是TCaplusValueFlag_ALLVALUE, 不合理场景
如果设置的是TCaplusValueFlag_ALLOLDVALUE, 如果获取到了tcapsvr端的数据则返回tcpasvr端的数据,如果没有获取到tcapsvr端的数据则返回空
6. TCAPLUS_API_LIST_DELETE_BATCH_REQ
如果设置的是TCaplusValueFlag_NOVALUE, 则操作失败后不返回数据
如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作失败后返回和请求一致的数据, 暂时没有实现
如果设置的是TCaplusValueFlag_ALLVALUE, 不合理场景
如果设置的是TCaplusValueFlag_ALLOLDVALUE, 则操作成功后返回tcapsvr端操作前的数据, 凡是本次成功删除的index对应的数据都会返回
7. TCAPLUS_API_LIST_ADDAFTER_REQ
如果设置的是TCaplusValueFlag_NOVALUE, 则操作失败后不返回数据
如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作失败后返回和请求一致的数据, 暂时没有实现
如果设置的是TCaplusValueFlag_ALLVALUE, 不合理场景
如果设置的是TCaplusValueFlag_ALLOLDVALUE, 不返回数据
8. TCAPLUS_API_LIST_DELETE_REQ
如果设置的是TCaplusValueFlag_NOVALUE, 则操作失败后不返回数据
如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作失败后返回和请求一致的数据, 暂时没有实现
如果设置的是TCaplusValueFlag_ALLVALUE, 不合理场景
如果设置的是TCaplusValueFlag_ALLOLDVALUE, 如果获取到了tcapsvr端的数据则返回tcpasvr端的数据,如果没有获取到tcapsvr端的数据则返回空
9. TCAPLUS_API_LIST_REPLACE_REQ
如果设置的是TCaplusValueFlag_NOVALUE, 则操作失败后不返回数据
如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作失败后返回和请求一致的数据, 暂时没有实现
如果设置的是TCaplusValueFlag_ALLVALUE, 不合理场景
如果设置的是TCaplusValueFlag_ALLOLDVALUE, 如果获取到了tcapsvr端的数据则返回tcpasvr端的数据,如果没有获取到tcapsvr端的数据则返回空
@param [IN] result_flag 请求标志:
0表示: 只需返回操作执行成功与否
1表示: 返回与请求字段一致
2表示: 须返回变更记录的所有字段最新数据
3表示: 须返回变更记录的所有字段旧数据
从而知道是哪个key对应的记录失败了
@retval 0 设置成功
@retval <0 失败,返回对应的错误码。通常因为未初始化。
*/
int SetResultFlagForFail (char result_flag);
/**
@brief 获取响应标志
@return 返回响应标志
*/
char GetResultFlag() const;
/**
@brief 获取响应标志, 主要是采用 SetResultFlagForSuccess设置的值
@return 返回响应标志
*/
char GetResultFlagForSuccess () const;
/**
@brief 获取响应标志, 主要是采用SetResultFlagForFail设置的值
@return 返回响应标志
*/
char GetResultFlagForFail () const;
/**
@brief 设置是否允许一个请求包可以自动响应多个应答包,仅对ListGetAll和Batch协议有效。
@param [IN] multi_flag 多响应包标示,1表示允许一个请求包可以自动响应多个应答包, 0表示不允许一个请求包自动响应多个应答包
@retval 0 设置成功
@retval <0 设置失败,具体错误参见 \link ErrorCode \endlink
@note 分包应答,目前只支持ListGetAll和Batch操作;其他操作设置该值是没有意义的,函数会返回<0的错误码。
*/
int32_t SetMultiResponseFlag(IN char multi_flag);
6. 响应对象(response)中的方法说明
注:此处未列出的响应对象的其它方法,即表示该方法在查询数据的场景不需要使用,误用可能会导致报错。
/**
@brief 获取请求操作的表名
@param [OUT] table_name_size 若table_name_size不为NULL,则向其所指位置写入表名长度,
该长度包括结尾的'\0'。
@retval NULL TcaplusServiceResponse对象未初始化时返回NULL。
@retval !NULL 指向操作的表名的指针。
*/
const char* GetTableName(OUT size_t* table_name_size = NULL) const;
/** \brief 获取操作结果
* \retval 0 操作结果成功
* \retval >0 操作结果警告,例如Get或删除一个不存在的数据记录则retval为TcapErrCode::TXHDB_ERR_RECORD_NOT_EXIST,具体错误参见 \link ErrorCode \endlink
* \retval <0 操作结果错误,例如写数据失败则retval为TcapErrCode::SVR_ERR_FAIL_WRITE_RECORD,具体错误参见 \link ErrorCode \endlink
*/
int32_t GetResult() const;
/**
@brief 获取APPID
@retval 非0 返回响应包中的app_id
@retval 0 当对象未初始化或尚未解析过响应包时,默认返回0
*/
int64_t GetAppId() const;
/**
@brief 获取ZoneId
@retval 非0 返回响应包中的zond_id
@retval 0 当对象未初始化或尚未解析过响应包时,默认返回0
*/
int GetZoneId() const;
/**
@brief 获取结果操作类型
@retval \link TCaplusApiCmds \endlink
*/
TCaplusApiCmds GetCmd() const;
/**
@brief 获取请求子操作类型,对document操作才有意义
@retval \link TCaplusApiCmds \endlink
*/
uint32_t GetSubCmd() const;
/**
@brief 获取结果异步事务ID
@retval 异步事务ID
*/
uint64_t GetAsynID() const;
/**
@brief 获取结果序列号
@retval 响应序列号
*/
int32_t GetSequence() const;
/**
@brief 获取响应的通用标志位
@return 返回响应的通用标志位
@note 有效的标志位列表及详细解释请参考 TcaplusServiceRequest::SetFlags(int)
*/
int32_t GetFlags() const;
/**
@brief 获取响应中的用户缓存信息
@param [out] buffer_data_size 用户缓存数据大小,若buffer_data_size不为NULL,则向其所指位置写入用户缓存数据的长度。
@retval NULL 当TcaplusServiceResponse对象未初始化时返回NULL。
@retval !NULL 用户缓存的首指针。
*/
const char* GetUserBuff(OUT size_t* buffer_data_size = NULL) const;
/**
@brief 获取本响应中结果记录条数
@retval 本响应中结果记录条数
*/
int32_t GetRecordCount() const;
/**
@brief 从结果中获取一条记录
@param [OUT] 指向返回记录的指针
@retval 0 获取记录成功
@retval 非0 获取记录失败
@note 通过此函数获取到本次操作的TcaplusServiceRecord对象后,上次操作获取到的TcaplusServiceRecord对象会被覆盖.
*/
int32_t FetchRecord(OUT const TcaplusServiceRecord*& record);
/**
@brief 可视化输出
@param [INOUT] buffer 缓冲区指针
@param [IN] buffer_size 缓冲区大小
@retval 打包的缓冲区指针,内容以'\0'结尾
*/
const char* Print(INOUT char* buffer, IN size_t buffer_size);
/**
@brief 是否还有更多回包用于传递所请求的结果Records。
@retval 0 没有更多回包了
@retval 1 还有更多回包
@retval < 0 操作失败,具体错误参见 \link ErrorCode \endlink
@note 该函数支持generic表和list表的Batch操作,以及ListGetAll, getbypartkey, updatebypartkey, deletebypartkey 操作
*/
int32_t HaveMoreResPkgs();
/**
@brief 获取本响应返回的第一条记录在整个结果集中的位置下标,从0开始编号
@retval 本响应返回的第一条记录在整个结果集中的位置下标,从0开始编号,
当GetRecordMatchOffset()+GetRecordCount() = GetRecordMatchCount() 说明已经返回符合条件的所有记录
*/
int32_t GetRecordMatchOffset() const;
/**
@brief 对于设置offset, limit的分配查询,该接口获取获取下一批的起始offset。仅LIST_GETALL, GET_BY_PARTKEY有效
@retval >= 0 下一批的起始offset
@retval -1 已经没有更多的记录
*/
int32_t GetRecordNextOffset() const;
/**
@brief 获取整个结果中的记录条数。既包括本响应返回的记录数,也包括本响应未返回的记录数。
@retval 记录条数
@note 该函数只能用于以下请求:
(1)TCAPLUS_API_GET_BY_PARTKEY_REQ(部分key查询);
(2)TCAPLUS_API_LIST_GETALL_REQ(list表查询所有匹配的记录);
(3)TCAPLUS_API_BATCH_GET_REQ(批量查询)
@note 该函数的作用是:
(1)当使用了SetResultLimit()来限制返回的记录时,
使用该函数可以获取所有匹配的记录的个数,
包括本响应返回的记录数和本响应未返回的记录数,
而GetRecordCount()函数只能获取本响应返回的记录的个数;
(2)当所返回的记录很多时,需要分包的时候,
使用该函数可以获取总共的记录数,
即多个分包所有记录数的总和,
而GetRecordCount()函数只能返回单个分包中的(本响应中的)记录数.
(3) 当有过滤条件时,该接口返回的不是满足条件的记录数,而是所有总记录数,这里由于历史原因命名上有些误导
*/
int32_t GetRecordMatchCount() const;
7. 记录对象(record)中的方法说明
注:此处未列出的响应对象的其它方法,即表示该方法在查询数据的场景不需要使用,误用可能会导致报错。
record的通用方法:
/** @brief 设置记录版本号 @param [IN] iVersion 数据记录的版本号: <=0 表示不关注版本号不关心版本号。具体含义如下。 当class TcaplusServiceRequest的int SetCheckDataVersionPolicy(enum tagCHECKDATAVERSIONTYPE type)函数传入的参数type的值为CHECKDATAVERSION_AUTOINCREASE时: 表示检测记录版本号。如果class TcaplusServiceRecord的void SetVersion(IN int32_t iVersion)函数传入的参数iVersion的值<=0,则仍然表示不关心版本号不关注版本号;如果class TcaplusServiceRecord的void SetVersion(IN int32_t iVersion)函数传入的参数iVersion的值>0,那么只有当该版本号与服务器端的版本号相同时,Replace, Update, Increase, ListAddAfter, ListDelete, ListReplace, ListDeleteBatch操作才会成功同时在服务器端该版本号会自增1。 当class TcaplusServiceRequest的int SetCheckDataVersionPolicy(enum tagCHECKDATAVERSIONTYPE type)函数传入的参数type的值为NOCHECKDATAVERSION_OVERWRITE时: 表示不检测记录版本号。如果class TcaplusServiceRecord的void SetVersion(IN int32_t iVersion)函数传入的参数iVersion的值<=0,则会把版本号1写入服务端的数据记录版本号(服务器端成功写入的数据记录的版本号最少为1);如果class TcaplusServiceRecord的void SetVersion(IN int32_t iVersion)函数传入的参数iVersion的值>0,那么会把该版本号写入服务端的数据记录版本号。 当class TcaplusServiceRequest的int SetCheckDataVersionPolicy(enum tagCHECKDATAVERSIONTYPE type)函数传入的参数type的值为NOCHECKDATAVERSION_AUTOINCREASE时: 表示不检测记录版本号,将服务器端的数据记录版本号自增1,若服务器端新写入数据记录则新写入的数据记录的版本号为1。 @retval void */ //Attention, 注意,对于Generic操作表示设置Record的版本,对于List操作表示设置Record所在List单元的版本。 void SetVersion(IN int32_t iVersion); /** @brief 获取记录版本号 @retval 记录版本号 @note 对于Generic操作表示获取Record的版本;对于List操作表示获取Record所在List的版本。 */ int32_t GetVersion() const; /** @brief 基于TDR描述设置record的过滤条件 @param [IN] condition 条件语句 @retval 0 设置成功 @retval <0 设置失败,具体错误参见 \link ErrorCode \endlink */ int32_t SetCondition(const std::string &condition); /** @brief 基于TDR描述设置record中数组的操作语句 @param [IN] operation 操作语句,包括 PUSH / POP / SET / GET @param [IN] operateOption 操作选项,仅 GET 有用,见 enum RecordOperationOption @retval 0 设置成功 @retval <0 设置失败,具体错误参见 \link ErrorCode \endlink */ int32_t SetOperation(const std::string &operation, int operateOption = 0);
record可以基于TDR结构设置和提取记录
/** @brief 基于TDR描述设置record数据 @param [IN] data_buffer 数据缓冲区 @param [IN] data_size 数据缓冲区大小 @param [IN] data_version 数据版本号,参看SetVersion函数。默认值-1表示写操作时不校验版本号, 不关心版本号. data_version为<=0都表示写操作时不会校验版本号, 不关心版本号 @param [IN] data_meta 数据缓冲区的数据对应的meta描述;NULL则自动使用request设置的默认meta信息,参看对应的SetTable函数。 @param [IN] partkey_index_name 部分键查询的索引名称。 @retval 0 设置成功 @retval <0 设置失败,具体错误参见 \link ErrorCode \endlink */ int32_t SetData(IN const void* data_buffer, IN size_t data_size, IN int32_t data_version = -1, IN LPTDRMETA data_meta = NULL, IN const char* partkey_index_name = NULL); /** @brief 基于TDR描述获取record数据 @param [OUT] data_buffer 数据缓冲区;必须先通过 memset 或者 tdr_init 对其进行初始化 @param [IN] data_size 数据缓冲区大小 @param [OUT] data_version 数据版本号,参看GetVersion函数。 @param [IN] data_meta 要取的数据对应的meta描述;NULL则自动使用response设置的默认meta信息,参看对应的SetTable函数。 @retval 0 设置成功 @retval <0 设置失败,具体错误参见 \link ErrorCode \endlink */ int32_t GetData(OUT void* data_buffer, IN size_t data_buffer_size, OUT int32_t* data_version = NULL, IN LPTDRMETA data_meta = NULL) const;
record同时支持通过SetKey SetValue接口设置记录中的字段,通过GetKey GetValue接口提取记录中的字段,但是SetKey、SetValue、GetKey、GetValue同SetData、GetData接口不可混用
- SetKey SetValue接口设置的数据,只能通过GetKey,GetValue接口读取;SetKey SetValue在使用batch命令时需要注意,record设置完成后调用Pack()把记录打包;SetData是一次性的,函数调用会自动打包,而SetKey SetValue不确定用户什么时候设置完最后一个字段,所以需要用户设置完kv后调用Pack()把记录打包;
- SetData接口设置的数据,只能通过GetData读取
/**
@brief 通用的key字段内容设置
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [IN] field_value 字段内容,最大长度1024字节
@param [IN] value_size 字段内容长度
@retval 0 设置成功
@retval 非0 设置失败,具体错误参见 \link ErrorCode \endlink
*/
int SetKey(IN const char* field_name, IN const void * field_value, IN const size_t value_size);
/**
@brief int8_t类型key字段内容设置
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [IN] field_value 字段内容
@retval 0 设置成功
@retval 非0 设置失败,具体错误参见 \link ErrorCode \endlink
*/
int SetKeyInt8(IN const char* field_name, IN const int8_t field_value);
/**
@brief int16_t类型key字段内容设置
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [IN] field_value 字段内容
@retval 0 设置成功
@retval 非0 设置失败,具体错误参见 \link ErrorCode \endlink
*/
int SetKeyInt16(IN const char* field_name, IN const int16_t field_value);
/**
@brief int32_t类型key字段内容设置
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [IN] field_value 字段内容
@retval 0 设置成功
@retval 非0 设置失败,具体错误参见 \link ErrorCode \endlink
*/
int SetKeyInt32(IN const char* field_name, IN const int32_t field_value);
/**
@brief int64_t类型key字段内容设置
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [IN] field_value 字段内容
@retval 0 设置成功
@retval 非0 设置失败,具体错误参见 \link ErrorCode \endlink
*/
int SetKeyInt64(IN const char* field_name, IN const int64_t field_value);
/**
@brief float类型key字段内容设置
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [IN] field_value 字段内容
@retval 0 设置成功
@retval 非0 设置失败,具体错误参见 \link ErrorCode \endlink
*/
int SetKeyFloat(IN const char* field_name, IN const float field_value);
/**
@brief double类型key字段内容设置
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [IN] field_value 字段内容
@retval 0 设置成功
@retval 非0 设置失败,具体错误参见 \link ErrorCode \endlink
*/
int SetKeyDouble(IN const char* field_name, IN const double field_value);
/**
@brief string类型key字段内容设置
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [IN] field_value 字段内容,最大长度1024字节,以'\0'结尾
@retval 0 设置成功
@retval 非0 设置失败,具体错误参见 \link ErrorCode \endlink
*/
int SetKeyStr(IN const char* field_name, IN const char* field_value);
/**
@brief blob类型key字段内容设置
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [IN] field_value 字段内容,最大长度1024字节
@param [IN] value_size 字段内容长度
@retval 0 设置成功
@retval 非0 设置失败,具体错误参见 \link ErrorCode \endlink
*/
int SetKeyBlob(IN const char* field_name, IN const char* field_value, IN const size_t value_size);
/**
@brief 通用的value字段内容设置
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [IN] field_value 字段内容,最大长度128KB(Tcapsvr>=3.24.0时,最大长度支持256KB)
@param [IN] value_size 字段内容长度
@retval 0 设置成功
@retval 非0 设置失败,具体错误参见 \link ErrorCode \endlink
*/
int SetValue(IN const char* field_name, IN const void * field_value, IN const size_t value_size);
/**
@brief int8_t类型value字段内容设置
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [IN] field_value 字段内容
@retval 0 设置成功
@retval 非0 设置失败,具体错误参见 \link ErrorCode \endlink
*/
int SetValueInt8(IN const char* field_name, IN const int8_t field_value);
/**
@brief int16_t类型value字段内容设置
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [IN] field_value 字段内容
@retval 0 设置成功
@retval 非0 设置失败,具体错误参见 \link ErrorCode \endlink
*/
int SetValueInt16(IN const char* field_name, IN const int16_t field_value);
/**
@brief int32_t类型value字段内容设置
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [IN] field_value 字段内容
@retval 0 设置成功
@retval 非0 设置失败,具体错误参见 \link ErrorCode \endlink
*/
int SetValueInt32(IN const char* field_name, IN const int32_t field_value);
/**
@brief int64_t类型value字段内容设置
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [IN] field_value 字段内容
@retval 0 设置成功
@retval 非0 设置失败,具体错误参见 \link ErrorCode \endlink
*/
int SetValueInt64(IN const char* field_name, IN const int64_t field_value);
/**
@brief float类型value字段内容设置
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [IN] field_value 字段内容
@retval 0 设置成功
@retval 非0 设置失败,具体错误参见 \link ErrorCode \endlink
*/
int SetValueFloat(IN const char* field_name, IN const float field_value);
/**
@brief double类型value字段内容设置
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [IN] field_value 字段内容
@retval 0 设置成功
@retval 非0 设置失败,具体错误参见 \link ErrorCode \endlink
*/
int SetValueDouble(IN const char* field_name, IN const double field_value);
/**
@brief string类型value字段内容设置
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [IN] field_value 字段内容,最大长度128K字节(Tcapsvr>=3.24.0时,最大长度支持256KB),以'\0'结尾
@retval 0 设置成功
@retval 非0 设置失败,具体错误参见 \link ErrorCode \endlink
*/
int SetValueStr(IN const char* field_name, IN const char* field_value);
/**
@brief blob类型value字段内容设置
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [IN] field_value 字段内容,最大长度128K字节(Tcapsvr>=3.24.0时,最大长度支持256KB)
注意:对于Blob,系统预留了2B用于版本号建设,因此,写入时数据不要超过(最大长度-2B)
@param [IN] value_size 字段内容长度
@retval 0 设置成功
@retval 非0 设置失败,具体错误参见 \link ErrorCode \endlink
*/
int SetValueBlob(IN const char* field_name, IN const char* field_value, IN const size_t value_size);
/**
@brief 通用的key字段内容获取
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [OUT] field_value 字段内容,最大长度1024字节
@param [OUT] value_size 字段内容长度
@retval 0 获取成功
@retval 非0 获取失败,具体错误参见 \link ErrorCode \endlink
*/
int32_t GetKey(IN const char* field_name, OUT void *& field_value, OUT size_t & value_size) const;
/**
@brief int8_t类型的key字段内容获取
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [OUT] field_value 字段内容
@retval 0 获取成功
@retval 非0 获取失败,具体错误参见 \link ErrorCode \endlink
*/
int32_t GetKeyInt8(IN const char* field_name, OUT int8_t & field_value) const;
/**
@brief int16_t类型的key字段内容获取
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [OUT] field_value 字段内容
@retval 0 获取成功
@retval 非0 获取失败,具体错误参见 \link ErrorCode \endlink
*/
int32_t GetKeyInt16(IN const char* field_name, OUT int16_t & field_value) const;
/**
@brief int32_t类型的key字段内容获取
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [OUT] field_value 字段内容
@retval 0 获取成功
@retval 非0 获取失败,具体错误参见 \link ErrorCode \endlink
*/
int32_t GetKeyInt32(IN const char* field_name, OUT int32_t & field_value) const;
/**
@brief int64_t类型的key字段内容获取
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [OUT] field_value 字段内容
@retval 0 获取成功
@retval 非0 获取失败,具体错误参见 \link ErrorCode \endlink
*/
int32_t GetKeyInt64(IN const char* field_name, OUT int64_t & field_value) const;
/**
@brief float类型的key字段内容获取
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [OUT] field_value 字段内容
@retval 0 获取成功
@retval 非0 获取失败,具体错误参见 \link ErrorCode \endlink
*/
int32_t GetKeyFloat(IN const char* field_name, OUT float & field_value) const;
/**
@brief double类型的key字段内容获取
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [OUT] field_value 字段内容
@retval 0 获取成功
@retval 非0 获取失败,具体错误参见 \link ErrorCode \endlink
*/
int32_t GetKeyDouble(IN const char* field_name, OUT double & field_value) const;
/**
@brief string类型的key字段内容获取
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [OUT] field_value 字段内容,最大长度1024字节,以'\0'结尾
@retval 0 获取成功
@retval 非0 获取失败,具体错误参见 \link ErrorCode \endlink
*/
int32_t GetKeyStr(IN const char* field_name, OUT const char*& field_value) const;
/**
@brief blob类型的key字段内容获取
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [OUT] field_value 字段内容,最大长度1024字节
@param [OUT] value_size 字段内容长度
@retval 0 获取成功
@retval 非0 获取失败,具体错误参见 \link ErrorCode \endlink
*/
int32_t GetKeyBlob(IN const char* field_name, OUT const char*& field_value, OUT size_t & value_size) const;
/**
@brief key字段数目获取
@retval 0 Key字段(Key Field)数目
*/
uint32_t GetKeyCount() const;
/**
@brief key字段内容获取
@param [IN] fieldIndex 字段下标,其有效值必须大于等于0并且小于GetKeyNum()
@param [OUT] field_name 字段名称,是字符串
@param [OUT] field_value 字段内容,最大长度1024字节
@param [OUT] value_size 字段内容长度
@retval 0 获取成功
@retval 非0 获取失败,具体错误参见 \link ErrorCode \endlink
*/
int32_t GetKey(IN uint32_t fieldIndex, OUT const char*& field_name, OUT const void *& field_value, OUT size_t& fieldValueLen) const;
/**
@brief 通用的value字段内容获取
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [OUT] field_value 字段内容,最大长度128K字节
@param [OUT] value_size 字段内容长度
@retval 0 获取成功
@retval 非0 获取失败,具体错误参见 \link ErrorCode \endlink
*/
int32_t GetValue(IN const char* field_name, OUT void *& field_value, OUT size_t & value_size) const;
/**
@brief int8_t类型的value字段内容获取
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [OUT] field_value 字段内容
@retval 0 获取成功
@retval 非0 获取失败,具体错误参见 \link ErrorCode \endlink
*/
int32_t GetValueInt8(IN const char* field_name, OUT int8_t & field_value) const;
/**
@brief int16_t类型的value字段内容获取
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [OUT] field_value 字段内容
@retval 0 获取成功
@retval 非0 获取失败,具体错误参见 \link ErrorCode \endlink
*/
int32_t GetValueInt16(IN const char* field_name, OUT int16_t & field_value) const;
/**
@brief int32_t类型的value字段内容获取
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [OUT] field_value 字段内容
@retval 0 获取成功
@retval 非0 获取失败,具体错误参见 \link ErrorCode \endlink
*/
int32_t GetValueInt32(IN const char* field_name, OUT int32_t & field_value) const;
/**
@brief int64_t类型的value字段内容获取
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [OUT] field_value 字段内容
@retval 0 获取成功
@retval 非0 获取失败,具体错误参见 \link ErrorCode \endlink
*/
int32_t GetValueInt64(IN const char* field_name, OUT int64_t & field_value) const;
/**
@brief float类型的value字段内容获取
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [OUT] field_value 字段内容
@retval 0 获取成功
@retval 非0 获取失败,具体错误参见 \link ErrorCode \endlink
*/
int32_t GetValueFloat(IN const char* field_name, OUT float & field_value) const;
/**
@brief double类型的value字段内容获取
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [OUT] field_value 字段内容
@retval 0 获取成功
@retval 非0 获取失败,具体错误参见 \link ErrorCode \endlink
*/
int32_t GetValueDouble(IN const char* field_name, OUT double & field_value) const;
/**
@brief string类型的value字段内容获取
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [OUT] field_value 字段内容,最大长度128K字节(Tcapsvr>=3.24.0时,最大长度支持256KB),以'\0'结尾
@retval 0 获取成功
@retval 非0 获取失败,具体错误参见 \link ErrorCode \endlink
*/
int32_t GetValueStr(IN const char* field_name, OUT const char*& field_value) const;
/**
@brief blob类型的value字段内容获取
@param [IN] field_name 字段名称,最大长度32字节,以'\0'结尾
@param [OUT] field_value 字段内容,最大长度128K字节(Tcapsvr>=3.24.0时,最大长度支持256KB)
@param [OUT] value_size 字段内容长度
@retval 0 获取成功
@retval 非0 获取失败,具体错误参见 \link ErrorCode \endlink
*/
int32_t GetValueBlob(IN const char* field_name, OUT const char*& field_value, OUT size_t & value_size) const;
/**
@brief Value字段数目获取
* \retval 0 Value字段(Value Field)数目
*/
uint32_t GetValueCount() const;
/**
@brief Value字段内容获取
* \param [IN] fieldIndex 字段下标,其有效值必须大于等于0并且小于GetValueNum()
* \param [OUT] field_name 字段名称,是字符串
* \param [OUT] field_value 字段内容,最大长度128K字节(Tcapsvr>=3.24.0时,最大长度支持256KB)
* \param [OUT] value_size 字段内容长度
* \retval 0 获取成功
* \retval 非0 获取失败,具体错误参见 \link ErrorCode \endlink
*/
int32_t GetValue(IN int fieldIndex, OUT const char*& field_name, OUT const void *& field_value, OUT size_t& fieldValueLen) const;
8. 常见问题
详见错误码含义和处理方法。
8. 其它参考文档
[TDR Generic表][Java SDK]扫描全表数据接口说明